﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public abstract class CameraLevel : MonoBehaviour
{
    [System.Serializable]
    public enum LevelType
    {
        Normal = 0,
        Pseudo3D,
        Brideye,
    }



    [Header("基础设置")]
    [Tooltip("摄像头左边界")]
    public float minRight = 6f;
    [Tooltip("摄像头右边界")]
    public float maxRight = 200f;
    [Tooltip("玩家角色预制件")]
    protected GameObject playerPrefab;
    [Tooltip("兰斯的生命面板，单人游戏不显示")]
    protected GameObject lanceLifePanelObject;
    [Tooltip("关卡的类型，正常、伪3D、俯视")]
    public LevelType levelType = LevelType.Normal;

    [Header("场景开始配置")]
    [Tooltip("场景开始时的开幕动作")]
    public SeqAction beginPerformanceAction = new() { beginWaitTime = 0.1f, intervalTime = 0 };
    [Tooltip("玩家角色生成动作，场景开始时与开幕动作配合")]
    public SeqAction playerBornAction = new() { beginWaitTime = 1.5f, intervalTime = 0 };

    [Header("出场人物")]
    [Tooltip("比尔")]
    public bool billRizer = true;
    [Tooltip("兰斯")]
    public bool lanceBean = true;
    [Tooltip("出场人物生命是否结束")]
    private readonly Dictionary<PlayerContext.EnumPlayer, bool> playerGameOver = new();

    [Header("音乐配置")]
    protected AudioSource backgroundSound;
    public AudioSource soundEffect;

    protected void Init(){
        ContraGlobal.currentLevel=this.GetLevelNo()-1;
        lanceLifePanelObject = GameObject.Find("生命面板-兰斯");
        lanceLifePanelObject.SetActive(ContraGlobal.IsTwoPlayers());
        backgroundSound = transform.Find("背景音乐").GetComponent<AudioSource>();
        soundEffect = transform.Find("音效").GetComponent<AudioSource>();
        playerPrefab = Constant.Player.ContraPlayer;
    }
    protected GameObject CreatePlayer(PlayerContext.EnumPlayer playerType)
    {
        GameObject playerObj = Instantiate(playerPrefab, Vector2.zero, Quaternion.identity);
        if (playerObj.TryGetComponent(out Player player))
        {
            player.PlayerIdentity = playerType;
        }

        if (playerGameOver.ContainsKey(playerType))
        {
            playerGameOver[playerType] = false;
        }
        else
        {
            playerGameOver.Add(playerType, false);
        }

        return playerObj;
    }
    public void GameOver(PlayerContext.EnumPlayer playerType)
    {
        if (playerGameOver.ContainsKey(playerType))
        {
            playerGameOver[playerType] = true;
        }
        else
        {
            playerGameOver.Add(playerType, true);
        }

        bool allGameOver = true;
        foreach (bool v in playerGameOver.Values)
        {
            if (!v)
            {
                allGameOver = false;
                break;
            }
        }
        if (allGameOver)
        {
            GoGameOverScene();
        }
    }

    protected void GoGameOverScene()
    {
        SceneManager.LoadScene(ContraGlobal.SceneName_GameOver, LoadSceneMode.Single);
    }

    public void ScenceFinshed()
    {
        GameObject.FindGameObjectsWithTag("Player").Action((GameObject playerObject) =>
        {
            Destroy(playerObject);
        });

        ContraGlobal.currentLevel++;
        SceneManager.LoadScene(ContraGlobal.SceneName_Map, LoadSceneMode.Single);
    }

    public virtual void Pause()
    {
        Constant.Sounds.Pause.PlayOneShot(soundEffect);
        backgroundSound.Pause();
        GameObject.FindObjectsOfType<AudioSource>().Action((AudioSource sound) =>
        {
            if (sound != soundEffect)
            {
                sound.Pause();
            }
        });
    }

    public virtual void UnPause()
    {
        backgroundSound.UnPause();
        GameObject.FindObjectsOfType<AudioSource>().Action((AudioSource sound) =>
        {
            if (sound != soundEffect)
            {
                sound.UnPause();
            }
        });
    }

    public static CameraLevel GetCurrentCamera(){
        CameraLevel ret=null;
        if(TryGetCurrentCamera(out CameraLevel cameraLevel)){
            ret=cameraLevel;
        }
        return ret;
    }
    public static bool TryGetCurrentCamera(out CameraLevel cameraLevel){
        return Camera.main.TryGetComponent(out cameraLevel);
    }

    public static AudioSource GetCurrentCameraSoundEffect(){
        TryGetCurrentCameraSoundEffect(out AudioSource ret);
        return ret;
    }
    public static bool TryGetCurrentCameraSoundEffect(out AudioSource soundEffect){
        bool ret=false;
        soundEffect=null;
        if(TryGetCurrentCamera(out CameraLevel cameraLevel)){
            soundEffect=cameraLevel.soundEffect;
        }
        ret=soundEffect!=null;
        return ret;
    }

    public void UpdateBeginPerformance()
    {
        beginPerformanceAction.Update((SeqAction seq) =>
        {
            SceneActDrop.Instance().Run(() =>
            {
                backgroundSound.loop = true;
                backgroundSound.Play();
            });
            seq.done = true;
        });
        playerBornAction.Update((SeqAction seq) =>
        {
            if (playerPrefab != null)
            {
                if (billRizer)
                {
                    CreatePlayer(PlayerContext.EnumPlayer.BillRizer);
                }
                if (lanceBean && ContraGlobal.IsTwoPlayers())
                {
                    CreatePlayer(PlayerContext.EnumPlayer.LanceBean);
                }
            }
            seq.done = true;
        });
    }

    public virtual bool HasElectricField(){
        return false;
    }

    public virtual bool Is3DLevel(){
        return false;
    }
    public virtual bool Is3DBossLevel(){
        return false;
    }

    public abstract int GetLevelNo();
}
